/**
 * @file    CTimerDispatcher.hpp
 * @date    2014-06-22
 * @author  Vladimir Prokopovich VProkopovich@gmail.com
 * @brief   Class CTimerDispatcher header file.
 *          Dispatcher of Timers
 */

#ifndef CTIMERDISPATCHER_HPP
#define CTIMERDISPATCHER_HPP

#include "CTimerCommand.hpp"

void HwTimerIsr();

const int TIMERS_MAX = 40;

class CTimerDispatcher
{
   public:
      // Members section

      /**
       * @brief   Returns a reference to this singletone object
       */
      static CTimerDispatcher& getInstance();
      
      /**
       * @brief Destructor
       * Does not free pData that is created by user
       */
      ~CTimerDispatcher();

      /**
       * @brief   Starts timer
       * @param intervalOnce     Timer once fires with this interval after start. If is set to 0, then timer starts to fire with intervalRepeat.
       * @param intervalRepeat   Timer once fires with this interval continuously. If is set to 0 intervalOnce is set to 0 timer would not be created successfully
       * @param pData            Data provided by user. Would be passed to callback function as an argument. is not freed by Timer module. 
       *                         !!! User is responsible for freeing memory !!!
       * @param callback         Callback method that is called when timeout fired
       * @return  Timer id if timer is created and started successfully.
       *          Returns 0 otherwise
       */
      unsigned int startTimer(const unsigned long long int& intervalOnce, const unsigned long long int& intervalRepeat, void* pData, CTimerCommand::tCallbackFunction callback);
      
      /**
       * @brief Stops specified timer
       * @note  Data associated to the timer is not freed. 
       *        User is responsible for freeing his data.
       * @param id   Identifier of a timer to be stopped
       */
      void stopTimer(unsigned int id);

      /**
       * @brief Inclass handler of HW interrupts
       */
      void processInterrupt();

   private:

      // Members section

      /**
       * @brief Default constructor
       */
      CTimerDispatcher();

      /**
       * @brief Copying constructor
       * Not implemented to avoid misusing
       */
      CTimerDispatcher(const CTimerDispatcher&);
      
      /**
       * @brief Assigning operator
       * Not implemented to avoid misusing
       */
      void operator=(const CTimerDispatcher&);

      /**
       * @brief Searches for the timer that should fire next
       *        criteria is - next fire time is smallest.
       * @return Pointer to an obkect
       */
      CTimerCommand* getNearestTimer() const;
      
      /**
       * @brief Schedules next timer if it is required
       */
      void scheduleNextTimer();

      // Data section

      unsigned int   mTimersCount;
      CTimerCommand* mTimerCommands[TIMERS_MAX];
      CTimerCommand* mpNextScheduledTimer;
};

#endif // CTIMERDISPATCHER_HPP